package com.remoter.transport.netty.filter;

import java.lang.reflect.Method;

import com.remoter.api.configure.IConfiguration;
import com.remoter.api.configure.support.AbstractConfiguration;
import com.remoter.api.context.IContextService;
import com.remoter.api.context.support.Exporter;
import com.remoter.api.extension.annotation.ExtensionName;
import com.remoter.api.extension.support.ExtensionLoader;
import com.remoter.api.protocol.support.RemoterRequest;
import com.remoter.api.protocol.support.RemoterResponse;
import com.remoter.api.transport.IMessageTaskFilter;
import com.remoter.api.util.Final;
import com.remoter.api.util.ObjectChain;
import com.remoter.api.util.StringUtil;

@ExtensionName("rpc")
public class RemoterProcedureMessageTaskFilter implements IMessageTaskFilter{
	
	private final IConfiguration configuration;
	private final IContextService contextService;
	public RemoterProcedureMessageTaskFilter(){
		this.configuration = AbstractConfiguration.getConfiguration();
		this.contextService = ExtensionLoader.getService(IContextService.class,this.configuration.getOption(Final.O_SERVER_CONTEXT));
	}
	
	@Override
	public void execute(RemoterRequest remoterRequest,RemoterResponse remoterResponse,ObjectChain<IMessageTaskFilter> chain) {
		try{
			String serviceClassString = remoterRequest.getServiceClass();
			String serviceBeanName = remoterRequest.getServiceBeanName();
			String serviceMethodName = remoterRequest.getServiceMethodName();
			if(StringUtil.isBlank(serviceClassString) || StringUtil.isBlank(serviceBeanName) || StringUtil.isBlank(serviceMethodName)){
				remoterResponse.setException("extension service data error for bean["+serviceBeanName+"]: " + serviceClassString + "." + serviceMethodName);
				return;
			}
			Class<?>[] serviceParamTypes = remoterRequest.getServiceParamTypes();
			Object[] serviceParamObjects = remoterRequest.getServiceParamObjects();
			Class<?> serviceClass = Class.forName(serviceClassString);
			
			Exporter service = this.contextService.getExporter(serviceBeanName,serviceClass);
			if(null == service){
				remoterResponse.setException("service instance not found : " + serviceClassString);
				return;
			}
			Method method = serviceClass.getMethod(serviceMethodName,serviceParamTypes);
			if(null == method){
				remoterResponse.setException("extension service method not found : " + serviceClassString + "." + serviceMethodName);
				return;
			}
			remoterResponse.setData(method.invoke(service.getInstance(),serviceParamObjects));
		}catch(Throwable e){
			remoterResponse.setException(e.getMessage());
		}
	}
	
}